#include <stdio.h>
#include <stdint.h>

/**
 * @brief 
 * This module can show a for loop progress through a ProgressBar
 * example:
 * ~~~C
 *      int maxCount = MAXCOUNT;
 *      InitProgressBar(maxCount,  50);
 *      for(int i = 0; i < maxCount; i++){
 *          UpdateProgressBar(i);
 *      }
 * ~~~
 * output:
 * --------------------------------------------------
 * ==================================================
 * 
 * This program may adjust ProgressBar length automatically.
 */


static uint64_t interval = 0;
static uint64_t _maxcount = 0;
static uint64_t _count = 0;
static uint8_t _theNumberOfBarPoints = 0;
static bool inited = 0;


static void _Updateinterval(){
    interval = _maxcount / _theNumberOfBarPoints;
}
static void GenerateNOBP(){ //Generate _theNumberOfBarPoints
    if(_maxcount < _theNumberOfBarPoints)
        _theNumberOfBarPoints = _maxcount;

    _Updateinterval();
    while(_maxcount / interval != _theNumberOfBarPoints){
        _theNumberOfBarPoints--;
        _Updateinterval();
    }
}

void InitProgressBar(int64_t maxCount, int8_t theNumberOfBarPoints){
    if(maxCount <= 0){
        printf("Error:ProgressBar is not inited, parameter maxCount got %lld.\n", maxCount);
        return ;
    }
    if(theNumberOfBarPoints <= 0){
        printf("Error:ProgressBar is not inited, parameter theNumberOfBarPoints got %lld.\n", theNumberOfBarPoints);
        return ;
    }
    _count = 0;
    _maxcount = maxCount;
    _theNumberOfBarPoints = theNumberOfBarPoints;
    GenerateNOBP();
    for(int8_t i = 0; i < _theNumberOfBarPoints; i++)    
        printf("_");
    printf("\n");
    inited = 1;
    return ;
}
static void _UpdateProgressBar(){
    if(_count % interval == 0)
        printf("=");
        fflush(stdout);
    if(_count == _maxcount)
        printf("\n");
    return ;
}
void UpdateProgressBar(int64_t count){
    if(!inited){
        printf("Error:ProgressBar is not inited.\n");
        return ;
    }
    while(_count <= count){
        _count++;
        _UpdateProgressBar();
    }
    return ;
}